{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\n",
    "Platypus是一个多目标优化库。这里我们将通过一个例子来简单介绍如何在Platypus中使用BAS。首先我们需要导入需要使用的函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "from platypus import Problem, Real\n",
    "from platypus.algorithms.bas import BAS\n",
    "from math import sin, pi, cos, exp, sqrt"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下一步，我们需要创建问题，这里我找了三个问题作为例子。\n",
    "\n",
    "第一个问题是\n",
    "# Goldstein and Price problem\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/goldpr.png)\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/goldpr2.png)\n",
    "---------------------------------------\n",
    "# Description:\n",
    "\n",
    "\n",
    "## Dimensions: 2\n",
    "\n",
    "Goldstein-Price有多个局部最优点. \n",
    "\n",
    "\n",
    "## Input Domain:\n",
    "\n",
    "The function is usually evaluated on the square xi ∈ [-2, 2], for all i = 1, 2. \n",
    "\n",
    "这个函数通常在正方形区间 xi ∈ [-2, 2]中进行评估，其中i = 1, 2.\n",
    "\n",
    "\n",
    "\n",
    "## Global Minima:\n",
    "\n",
    " ![](https://www.sfu.ca/~ssurjano/goldpr3.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "class gold(Problem):\n",
    "    def __init__(self):\n",
    "        super(gold, self).__init__(nvars=2, nobjs=1)\n",
    "        self.types[:] = [Real(-2, 2), Real(-2, 2)]\n",
    "\n",
    "    def evaluate(self, solution):\n",
    "        vars = solution.variables[:]\n",
    "        x1 = vars[0]\n",
    "        x2 = vars[1]\n",
    "        fact1a = (x1 + x2 + 1) ** 2\n",
    "        fact1b = 19 - 14 * x1 + 3 * x1 ** 2 - 14 * x2 + 6 * x1 * x2 + 3 * x2 ** 2\n",
    "        fact1 = 1 + fact1a * fact1b\n",
    "\n",
    "        fact2a = (2 * x1 - 3 * x2) ** 2\n",
    "        fact2b = 18 - 32 * x1 + 12 * x1 ** 2 + 48 * x2 - 36 * x1 * x2 + 27 * x2 ** 2\n",
    "        fact2 = 30 + fact2a * fact2b\n",
    "        solution.objectives[:] = [fact1 * fact2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MICHALEWICZ FUNCTION\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/michal.png)\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/michal2.png)\n",
    "\n",
    "# Description:\n",
    "\n",
    "## Dimensions: d \n",
    "\n",
    "The Michalewicz function has d! local minima, and it is multimodal. The parameter m defines the steepness of they valleys and ridges; a larger m leads to a more difficult search. The recommended value of m is m = 10. The function's two-dimensional form is shown in the plot above. \n",
    "\n",
    "## Input Domain:\n",
    "\n",
    "The function is usually evaluated on the hypercube xi ∈ [0, π], for all i = 1, …, d. \n",
    "\n",
    "## Global Minima:\n",
    "\n",
    " ![](https://www.sfu.ca/~ssurjano/michal3.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "class mich(Problem):\n",
    "    def __init__(self):\n",
    "        super(mich, self).__init__(nvars=2, nobjs=1)\n",
    "        self.types[:] = [Real(-6, -1), Real(0, 2)]\n",
    "\n",
    "    def evaluate(self, solution):\n",
    "        vars = solution.variables[:]\n",
    "        x1 = vars[0]\n",
    "        x2 = vars[1]\n",
    "        y1 = -sin(x1) * ((sin((x1 ** 2) / pi)) ** 20)\n",
    "        y2 = -sin(x2) * ((sin((2 * x2 ** 2) / pi)) ** 20)\n",
    "        solution.objectives[:] = [y1 + y2]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# ACKLEY函数（ACKLEY FUNCTION）\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/ackley.png)\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/ackley2.png)\n",
    "\n",
    "#Description:\n",
    "\n",
    "## Dimensions: d \n",
    "\n",
    "The Ackley function is widely used for testing optimization algorithms. In its two-dimensional form, as shown in the plot above, it is characterized by a nearly flat outer region, and a large hole at the centre. The function poses a risk for optimization algorithms, particularly hillclimbing algorithms, to be trapped in one of its many local minima. \n",
    "\n",
    "Recommended variable values are: a = 20, b = 0.2 and c = 2π. \n",
    "\n",
    "## Input Domain:\n",
    "The function is usually evaluated on the hypercube xi ∈ [-32.768, 32.768], for all i = 1, …, d, although it may also be restricted to a smaller domain. \n",
    "\n",
    "## Global Minimum:\n",
    "\n",
    " ![](https://www.sfu.ca/~ssurjano/ackley3.png)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Ackley(Problem):\n",
    "    def __init__(self):\n",
    "        super(Ackley, self).__init__(nvars=2, nobjs=1)\n",
    "        self.types[:] = [Real(-15, 30), Real(-15, 20)]\n",
    "\n",
    "    def evaluate(self, solution):\n",
    "        vars = solution.variables[:]\n",
    "        n = 2\n",
    "        a = 20\n",
    "        b = 0.2\n",
    "        c = 2 * pi\n",
    "        s1 = 0\n",
    "        s2 = 0\n",
    "        for i in range(n):\n",
    "            s1 = s1 + vars[i] ** 2\n",
    "            s2 = s2 + cos(c * vars[i])\n",
    "        y = -a * exp(-b * sqrt(1 / n * s1)) - exp(1 / n * s2) + a + exp(1)\n",
    "        solution.objectives[:] = [y]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "然后我们将每个问题构成一个单独的实例。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem = gold()\n",
    "problem2 = mich()\n",
    "problem3 = Ackley()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "接下来，我们创建BAS算法的实例。BAS算法中需要修改一些参数来获得更好的结果。例如第一个BAS实例中step=1,c=5。\n",
    "\n",
    "完成初始化后，我们可以针对不同的问题迭代不同的次数，例如第三个BAS实例中，算法迭代了300次。\n",
    "\n",
    "最后通过print函数读取最优解。可以直接输出solution这个类，他的输出顺序是\n",
    "\n",
    "**Solution[solution.variables|solution.objectives|solution.constraints]**\n",
    "\n",
    "\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Solution[-0.0024583254426162517,-1.002363921850713|3.0026888420039026|0]\n"
     ]
    }
   ],
   "source": [
    "algorithm = BAS(problem, step=1, c=5)\n",
    "algorithm.run(100)\n",
    "print(algorithm.best)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "当然也可以直接输出目标函数，例如算法实例2。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "下一步，我们需要创建问题，这里我找了三个问题作为例子。\n",
    "\n",
    "第一个问题是\n",
    "# Goldstein and Price problem\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/goldpr.png)\n",
    "\n",
    "![](https://www.sfu.ca/~ssurjano/goldpr2.png)\n",
    "---------------------------------------\n",
    "# Description:\n",
    "\n",
    "\n",
    "## Dimensions: 2\n",
    "\n",
    "Goldstein-Price有多个局部最优点. \n",
    "\n",
    "\n",
    "## Input Domain:\n",
    "\n",
    "The function is usually evaluated on the square xi ∈ [-2, 2], for all i = 1, 2. \n",
    "\n",
    "这个函数通常在正方形区间 xi ∈ [-2, 2]中进行评估，其中i = 1, 2.\n",
    "\n",
    "\n",
    "\n",
    "## Global Minima:\n",
    "\n",
    " ![](https://www.sfu.ca/~ssurjano/goldpr3.png)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "或者也可以通过格式化的方法获得更好的输出效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Variables = [1.52121543e-06 2.42423873e-06]\nObjective = [8.095169530708546e-06]\n"
     ]
    }
   ],
   "source": [
    "algorithm3 = BAS(problem3, step=30, c=0.1)\n",
    "algorithm3.run(300)\n",
    "print('Variables = {}\\nObjective = {}'.format(algorithm3.best.variables,algorithm3.best.objectives))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
